package co.fitstart.weapp.api.service.impl;

import java.util.Arrays;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.demo2do.core.entity.exception.BusinessException;
import com.demo2do.core.persistence.GenericDaoSupport;
import com.demo2do.core.persistence.annotation.Dao;
import com.demo2do.core.utils.DateFormatUtils;

import co.fitstart.entity.coupon.Coupon;
import co.fitstart.entity.coupon.CouponStatus;
import co.fitstart.entity.order.Order;
import co.fitstart.entity.user.User;
import co.fitstart.entity.utils.DateUtils;
import co.fitstart.weapp.api.dao.CouponDao;
import co.fitstart.weapp.api.dao.UserDao;
import co.fitstart.weapp.api.service.CouponService;

/**
 * 
 * @author dan
 *
 */
@Service("couponService")
public class CouponServiceImpl implements CouponService{

    @Dao
    private CouponDao couponDao;
    
    @Dao
    private UserDao userDao;

    @Autowired
    private GenericDaoSupport genericDaoSupport;
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.weapp.api.service.CouponService#listCoupon(co.fitstart.entity.user.User)
     */
    public List<Coupon> listCoupon(User user) {
        return couponDao.list(user.getId());
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.weapp.api.service.CouponService#listCoupon(co.fitstart.entity.order.Order)
     */
    public List<Coupon> listCoupon(Order order) {
        return couponDao.list(order);
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.weapp.api.service.CouponService#load(java.lang.Long)
     */
    public Coupon load(Long couponId) {
        return genericDaoSupport.load(Coupon.class, couponId);
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.weapp.api.service.CouponService#give(co.fitstart.entity.coupon.Coupon, co.fitstart.entity.user.User, co.fitstart.entity.user.User)
     */
    public void give(Coupon coupon, User from, User to) {
        if(coupon == null || !from.getId().equals(coupon.getUserId()) 
                || !coupon.getStatus().isClaimed() || coupon.getRestDay() <= 0 
                || coupon.getTemplate().getDiscountType().isFixedAmount() 
                || coupon.getOriginalUserId() != null) {
            throw new BusinessException("优惠券异常");
        } else if(to ==  null) {
            throw new BusinessException("不存在的受赠用户");
        } else if(to == from) {
            throw new BusinessException("不能转赠给自己");
        }
        
        Order order = coupon.getOrder();
        
        //check coupons from one online year order can only give one user
        List<Coupon> coupons = couponDao.list(order);
        for(Coupon eachCoupon : coupons) {
            if(!from.getId().equals(eachCoupon.getUserId()) && !to.getId().equals(eachCoupon.getUserId())) {
                throw new BusinessException("只能转赠给一个人");
            }
        }
        
        genericDaoSupport.update(coupon.give(from, to));
    }

    /*
     * (non-Javadoc)
     * @see co.fitstart.weapp.api.service.CouponService#give(co.fitstart.entity.coupon.Coupon, co.fitstart.entity.user.User, java.lang.String, java.lang.String)
     */
    public void give(Coupon coupon, User from, String name, String mobile) {
        if(coupon == null || !from.getId().equals(coupon.getUserId()) || !coupon.getStatus().isClaimed() || coupon.getRestDay() <= 0 || coupon.getOriginalUserId() != null || !coupon.getTemplate().isGiveAvailable()) {
            throw new BusinessException("优惠券异常");
        } else if(from.getMobile().equals(mobile)) {
            throw new BusinessException("不能转赠给自己");
        }
        
        Order order = coupon.getOrder();
        if(order != null) {
            List<Coupon> coupons = couponDao.list(order);
            for(Coupon eachCoupon : coupons) {
                if(!from.getId().equals(eachCoupon.getUserId()) && !mobile.equals(eachCoupon.getIdentification())) {
                    throw new BusinessException("只能转赠给一个人");
                }
            }
        }
        
        User to = userDao.loadByMobile(mobile);
        if(to == null) {
            genericDaoSupport.update(coupon.give(from, name, mobile));
        } else {
            if(StringUtils.isNotBlank(to.getName()) && !to.getName().equals(name)) {
                throw new BusinessException("姓名或手机号不匹配");
            }
            
            genericDaoSupport.update(coupon.give(from, to));
        }
    }

    /*
     * (non-Javadoc)
     * @see co.fitstart.weapp.api.service.CouponService#list(co.fitstart.entity.user.User, boolean)
     */
    public List<Coupon> list(User user, boolean available) {
        Date today = DateUtils.parseDate(DateFormatUtils.format(new Date(), "yyyy-MM-dd"), "yyyy-MM-dd");
        
        if(available) {
            return couponDao.listAvailable(user.getId(), CouponStatus.CLAIMED, today);
        } else {
            return couponDao.listUnavailable(user.getId(), CouponStatus.CLAIMED, Arrays.asList(new CouponStatus[]{CouponStatus.OCCUPIED, CouponStatus.OUT_OFF_DATE, CouponStatus.USED, CouponStatus.HOLD}), today);
        }
    }
}
